package com.fand.utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * Collections工具集.
 * 
 * @author yaoHT
 */
public class Collections3 {
	/**
	 * 提取集合中的对象的一个属性(通过Getter函数), 组合成List.
	 * 
	 * @param collection
	 *            来源集合.
	 * @param propertyName
	 *            要提取的属性名.
	 */
	public static List<Object> extractToList(final Collection<?> collection, final String propertyName) {
		final List<Object> list = Lists.newArrayList();
		
		try {
			for (final Object obj : collection) {
				list.add(PropertyUtils.getProperty(obj, propertyName));
			}
		} catch (final Exception e) {
			throw new RuntimeException(e);
		}
		
		return list;
	}
	
	/**
	 * 提取集合中的对象的两个属性(通过Getter函数), 组合成Map.
	 * 
	 * @param collection
	 *            来源集合.
	 * @param keyPropertyName
	 *            要提取为Map中的Key值的属性名.
	 * @param valuePropertyName
	 *            要提取为Map中的Value值的属性名.
	 */
	public static Map<Object, Object> extractToMap(final Collection<?> collection, final String keyPropertyName,
	        final String valuePropertyName) {
		final Map<Object, Object> map = Maps.newHashMap();
		
		try {
			for (final Object obj : collection) {
				map.put(PropertyUtils.getProperty(obj, keyPropertyName),
				        PropertyUtils.getProperty(obj, valuePropertyName));
			}
		} catch (final Exception e) {
			throw new RuntimeException(e);
		}
		
		return map;
	}
	
	/**
	 * 提取集合中的对象的一个属性(通过Getter函数), 组合成由分割符分隔的字符串.
	 * 
	 * @param collection
	 *            来源集合.
	 * @param propertyName
	 *            要提取的属性名.
	 * @param separator
	 *            分隔符.
	 */
	public static String extractToString(final Collection<?> collection, final String propertyName,
	        final String separator) {
		final List<?> list = Collections3.extractToList(collection, propertyName);
		
		return StringUtils.join(list, separator);
	}
	
	/**
	 * 取得Collection的第一个元素，如果collection为空返回null.
	 */
	public static <T> T getFirst(final Collection<T> collection) {
		if (CollectionUtils.isEmpty(collection)) { return null; }
		
		return collection.iterator().next();
	}
	
	/**
	 * 获取Collection的最后一个元素 ，如果collection为空返回null.
	 */
	public static <T> T getLast(final Collection<T> collection) {
		if (CollectionUtils.isEmpty(collection)) { return null; }
		
		// 当类型为List时，直接取得最后一个元素 。
		if (collection instanceof List) {
			final List<T> list = (List<T>) collection;
			
			return list.get(list.size() - 1);
		}
		
		// 其他类型通过iterator滚动到最后一个元素.
		final Iterator<T> iterator = collection.iterator();
		
		while (true) {
			final T current = iterator.next();
			if (!iterator.hasNext()) { return current; }
		}
	}
	
	/**
	 * 返回a与b的交集的新List.
	 */
	public static <T> List<T> intersection(final Collection<T> a, final Collection<T> b) {
		final List<T> list = new ArrayList<T>();
		
		for (final T element : a) {
			if (b.contains(element)) {
				list.add(element);
			}
		}
		return list;
	}
	
	/**
	 * 返回a-b的新List.
	 */
	public static <T> List<T> subtract(final Collection<T> a, final Collection<T> b) {
		final List<T> list = new ArrayList<T>(a);
		
		for (final T element : b) {
			list.remove(element);
		}
		
		return list;
	}
	
	/**
	 * 返回a+b的新List.
	 */
	public static <T> List<T> union(final Collection<T> a, final Collection<T> b) {
		final List<T> result = new ArrayList<T>(a);
		
		result.addAll(b);
		
		return result;
	}
}
